codeforces 254D

给出墙的位置和老鼠的位置,给你两个炸弹和炸弹爆炸秒数,炸弹不能炸或放在墙的位置,俩炸弹不能放在相同位置,炸弹每秒扩散方向为上下左右,要求炸死所有老鼠求炸弹放置位置。
地图范围是1000*1000。

枚举所有可以放置炸弹的地方,TLE。
这里我介绍一种剪枝的方法。设爆炸时间为d,我们先找第一个点,这个点一定是可以炸到第一个老鼠的,设这只老鼠为a。所以先枚举能炸到a的位置,然后用bfs爆炸第一个炸弹,并标记它炸到的位置和炸到的老鼠。然后再找第二个位置,这个位置一定是能炸到在第一个炸弹没炸到的老鼠b的,那么枚举能炸到b的位置,再用dfs爆炸第二个炸弹,如果炸死所有老鼠,就输出,否则就反悔这个位置,之前标记的地方全都进行反标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

#include<stdio.h>
#include<queue>
#include<vector>
#define pii pair<int,int>
#define piii pair<int ,pii>
using namespace std;

const int maxn=1003;
int n,m,d;
int rm[maxn][maxn]={0};
int wm[maxn][maxn]={0};
int fil[maxn][maxn]={0};
char s[maxn];
int totr=0,nowr;
int x1,y1,x2,y2;
queue<pii> rnum[2];

bool cango(int x,int y)
{

return x>=0&&x<n&&y>=0&&y<m&&wm[x][y]==0;
}
int X[]={0,0,1,-1},Y[]={1,-1,0,0};
void booom(int x,int y,int u)
{

queue<piii >q;
q.push(piii(0,pii(x,y)));
while(!q.empty())
{
int t=q.front().first;
x=q.front().second.first;
y=q.front().second.second;
q.pop();
if(!fil[x][y])
{
fil[x][y]=1;
if(rm[x][y])
nowr++;
rnum[u].push(pii(x,y));
}
if(t+1<=d)
for(int i=0;i<4;i++)
{
int tx=x+X[i],ty=y+Y[i];
if(cango(tx,ty))
q.push(piii(t+1,pii(tx,ty)));
}
}
}
void regret(int u)
{

while(!rnum[u].empty())
{
int x=rnum[u].front().first,y=rnum[u].front().second;
rnum[u].pop();
fil[x][y]=0;
if(rm[x][y])nowr--;
}
}
bool second_pos()
{

int x=x1,y=y1;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(rm[i][j]&&!fil[i][j])
{
x=i,y=j;
break;
}

for(int i=-d;i<=d;i++)
for(int j=-d;j+i<=d;j++)
{
x2=x+i,y2=y+j;
if(cango(x2,y2)&&(x1!=x2||y1!=y2))
{
booom(x2,y2,1);
if(nowr==totr)
return 1;
regret(1);
}
}
return 0;
}
bool first_pos()
{

int x,y;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(rm[i][j])
{
x=i,y=j;
break;
}

for(int i=-d;i<=d;i++)
for(int j=-d;j+i<=d;j++)
{
x1=x+i,y1=y+j;
if(cango(x1,y1))
{
nowr=0;
booom(x1,y1,0);
if(fil[x][y])
{
if(second_pos())
return 1;
}
regret(0);
}
}
return 0;
}
int main()
{

freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%d%d%d",&n,&m,&d);
for(int i=0;i<n;i++)
{
scanf("%s",s);
for(int j=0;j<m;j++)
if(s[j]=='R')
{
rm[i][j]=1;
totr++;
}
else if(s[j]=='X')wm[i][j]=1;
}
if(first_pos())printf("%d %d %d %d\n",x1+1,y1+1,x2+1,y2+1);
else puts("-1");
}

EOF